﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Coding4Fun.Cannon.Robot;
using Microsoft.WindowsAPICodePack.Sensors;

namespace Coding4Fun.Cannon.Wpf
{
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
		public MainWindow()
		{
			InitializeComponent();
		}

		
		private void Window_Loaded(object sender, RoutedEventArgs e)
		{
			SensorManager.SensorsChanged += SensorManager_SensorsChanged;
			HookUpAccelerometer();

			
		}

		public delegate void BlankDelegate();
		void SensorManager_SensorsChanged(SensorsChangedEventArgs change)
		{
			Dispatcher.Invoke((BlankDelegate)HookUpAccelerometer);
		}

		private void HookUpAccelerometer()
		{
			try
			{
				var sl = SensorManager.GetSensorsByTypeId<Accelerometer3D>();
				if (sl.Count > 0)
				{
					var accel = sl[0];
					accel.AutoUpdateDataReport = true;
					accel.DataReportChanged += (s, e) => Dispatcher.Invoke((BlankDelegate)delegate
					{
						var raw = accel.CurrentAcceleration[AccelerationAxis.Y];
						var forward = raw;
						if(Math.Abs(forward) < .1)
						{
							forward = 0;
						}

						forward *= 100;
						//var pan = accel.CurrentAcceleration[AccelerationAxis.Y];

						//pan *= 90; // -90 to 90
						//pan += 90; // 0 to 180 now.

						//if (pan < 0)
						//    pan = 0;
						//else if (pan > 180)
						//    pan = 180;

						//var tilt = accel.CurrentAcceleration[AccelerationAxis.X];
						//tilt *= -90; // -90 to 90
						//tilt += 90; // 0 to 180 now.

						//if (tilt < 50)
						//    tilt = 50;
						//else if (tilt > 170)
						//    tilt = 170;
						//AccelX = pan;
						//AccelY = tilt;
						//MakeServoRequest(AccelX, AccelY);
						Dispatcher.Invoke(new Action<Label, float, Label, float>((l1, v1, l2, v2) => { l1.Content = v1.ToString(); l2.Content = v2.ToString(); }), label1, forward, label2, raw);
						SetSpeed((int)forward, (int)forward);

					});
				}

				//AccelTotal = sl.Count;
			}
			catch (SensorPlatformException)
			{
				// This exception will also be hit in the Shown message handler.
			}
		}

		private void btnForward_Click(object sender, RoutedEventArgs e)
		{
			SetSpeed(15, 15);
		}

		private void btnRev_Click(object sender, RoutedEventArgs e)
		{
			SetSpeed(-15, -15);
		}

		private void btnStop_Click(object sender, RoutedEventArgs e)
		{
			SetSpeed(0, 0);
		}
		
		private void CallService(Uri url)
		{
			var request = (HttpWebRequest)WebRequest.Create(url);
			request.Method = "GET";

			request.BeginGetResponse(callback, request);
		}

		void callback(IAsyncResult result)
		{
			try
			{
				var response = ((HttpWebRequest)result.AsyncState).EndGetResponse(result);
				var reader = new StreamReader(response.GetResponseStream());
				string xml = reader.ReadToEnd();
				Debug.WriteLine(String.Format("response: {0}", xml));
			}
			catch (WebException wex)
			{
				//Web exception is happenning swallow/ignore
				Debug.WriteLine(String.Format("Exception: {0}", wex.Message));

			}
			catch (Exception ex)
			{
				//Throw on another exception type
				Debug.WriteLine(String.Format("Exception: {0}", ex.Message));
				throw;
			}

		}

		private string ipAddress = @"http://localhost/betty/";
		public void SetSpeed(int leftPower, int rightPower)
		{
			string command = "drive";
			Uri url = new Uri(String.Format("{0}?command={1}&leftpower={2}&rightpower={3}", ipAddress, command, leftPower, rightPower));
			CallService(url);
		}

		public void SetAim(double pan, double tilt)
		{
		}

		private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			SetAim();
		}

		private void slider2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			SetAim();
		}

		public void SetAim()
		{
			string command = "aim";
			Uri url = new Uri(String.Format("{0}?command={1}&pan={2}&tilt={3}", ipAddress, command, slider1.Value, slider2.Value));
			CallService(url);
		}

		public void SetFire()
		{
			string command = "fire";
			Uri url = new Uri(String.Format("{0}?command={1}", ipAddress, command));
			CallService(url);
		}

        public void SetHalt()
        {
            string command = "aimhalt";
            Uri url = new Uri(String.Format("{0}?command={1}", ipAddress, command));
            CallService(url);
        }

		private void button1_Click(object sender, RoutedEventArgs e)
		{
			slider1.Value = -90;
		}

		private void button2_Click(object sender, RoutedEventArgs e)
		{
			slider1.Value = 0;
		}

		private void button3_Click(object sender, RoutedEventArgs e)
		{
			slider1.Value = 90;
		}

		private void button4_Click(object sender, RoutedEventArgs e)
		{
			SetFire();
		}

        private void button5_Click(object sender, RoutedEventArgs e)
        {
            SetHalt();
        }

		private void button6_Click(object sender, RoutedEventArgs e)
		{
			var adjuster = Convert.ToDecimal(txtMovement.Text);
			currentAngle += adjuster;

			//string command = "aim";
			//Uri url = new Uri(String.Format("{0}?command={1}&pan={2}", ipAddress, command, currentAngle));
			//CallService(url);

			CallService("aim", "pan={0}&tilt={1}", currentAngle);
		}

		private void CallService(string command, string format, params object[] args)
		{
			ipAddress = string.Format("{0}?command=", ipAddress);
			var url = new Uri(String.Format(ipAddress + "?command=" + command + "&" + format.TrimStart('&'), args));
			CallService(url);
		}

		decimal currentAngle = 0;

		private void button7_Click(object sender, RoutedEventArgs e)
		{
			currentAngle = 0;
		}

	}
}
